#include <stdio.h>
#include <stdlib.h>

#define SIZE_MAX_MATRIX 128
#define SIZE_CHARLIST   SIZE_MAX_MATRIX*SIZE_MAX_MATRIX*4+1
char Char8List[SIZE_CHARLIST];
int **mat1 = NULL, **mat2 = NULL;
int MatrixSize=0;

void initCharList(){
    int i;
    for(i=0;i<SIZE_CHARLIST;i++){
        Char8List[i]=0;
    }
}


void free_MatrixMemory(int **Matrix){
    int i;
    for(i=0;i<MatrixSize;i++)
        free(Matrix[i]);
    free(Matrix);
    Matrix=NULL;
}

void ConvertMatrix(char destination[SIZE_CHARLIST], int **Matrix){
    int x=(MatrixSize>SIZE_MAX_MATRIX)?SIZE_MAX_MATRIX:MatrixSize;
    int y=x;
    int i,j;
    int ptr=0;
    
    
    
    for(i=0;i<x;i++){
        for(j=0;j<y;j++){
            ptr=i*x+j;
            memcpy(&destination[ptr<<2], &Matrix[i][j], sizeof(int));
            //destination[ptr<<2]=Matrix[i][j];
        }
    }
}

void RetrieveMatrix(char Source[SIZE_CHARLIST], int **Matrix){
    int x=(MatrixSize>SIZE_MAX_MATRIX)?SIZE_MAX_MATRIX:MatrixSize;
    int y=x;
    int i,j;
    int ptr=0;
    
    // free memory before allocation
    if(*Matrix!=NULL){
        free_MatrixMemory(Matrix);
    }
    
    // Retrieve information from char list
    for(i=0;i<x;i++){
        for(j=0;j<y;j++){
            ptr=i*x+j;
            //Matrix[i][j]=Source[ptr<<2];
            memcpy(&Matrix[i][j], &Source[ptr<<2], sizeof(int));
        }
    }
}

void Create_Matrix(){
    int i=0, j=0;
    //SYSTEM_2Print ("========== create a matrix of (%d x %d)  ==========\n", MatrixSize,MatrixSize);
    
    mat1=(int**) malloc(MatrixSize*sizeof(int*));
    for(i=0;i<MatrixSize;i++){
        mat1[i]=(int*) malloc(MatrixSize*sizeof(int));
    }
    mat2=(int**) malloc(MatrixSize*sizeof(int*));
    for(i=0;i<MatrixSize;i++){
        mat2[i]=(int*) malloc(MatrixSize*sizeof(int));
    }
}

void init_Matrix(int Size){
    int i,j;
    
    // Make sure request Matrix size is within valid region
    MatrixSize = (Size>SIZE_MAX_MATRIX)?SIZE_MAX_MATRIX:Size;
    
    // Remove allocated memory if assigned previously
    // Reset it to default value to prevent misuse
    if(mat1!=NULL){
        free_MatrixMemory(mat1);
    }
    if(mat2!=NULL){
        free_MatrixMemory(mat2);
    }
    
    // Allocate Memory for mat1 and mat2
    Create_Matrix();
    
    // Given equation for mat1 and mat2
    for (i = 0;i < MatrixSize; i++)
    {
        for (j = 0; j < MatrixSize; j++)
        {
            mat1[i][j] = i+j*9;
        }
    }
    for (i = 0;i < MatrixSize; i++)
    {
        for (j = 0; j < MatrixSize; j++)
        {
            mat2[i][j] = i+j*40;
        }
    }
}

void printMatrix(int size){
    int i,j;
    printf("Matrix 1:\n");
    for(i=0;i<size;i++){
        for(j=0;j<size;j++){
            printf("%d ",mat1[i][j]);
        }
        printf("\n");
    }
    printf("\n==============================\n");
    
    printf("Matrix 2:\n");
    for(i=0;i<size;i++){
        for(j=0;j<size;j++){
            printf("%d ",mat2[i][j]);
        }
        printf("\n");
    }
    printf("\n==============================\n");
}

int main(){
    int size=12;
    
    init_Matrix(size);
    initCharList();
    
    printMatrix(size);
    printf("\n**************************************\n");
    
    
    ConvertMatrix(Char8List,mat1);
    RetrieveMatrix(Char8List, mat1);
    ConvertMatrix(Char8List, mat2);
    RetrieveMatrix(Char8List, mat2);
    printMatrix(size);
    
    return 0;
}